import java.lang.invoke.CallSite;
import java.lang.invoke.ConstantCallSite;
import java.lang.invoke.MethodHandle;
import java.lang.invoke.MethodHandles;
import java.lang.invoke.MethodHandles.Lookup;
import java.lang.invoke.MethodType;

public class IndyHello {
    public static void say(String text1, String text2) {
	System.out.println(text1+" "+text2);
    }
    
    public static void main(String[] args) throws Throwable {
        MethodHandle indy = new DynamicIndyGenerator().invokeDynamic("hello",
                MethodType.methodType(void.class, String.class),
                IndyHello.class, "bootstrapMethod",
                MethodType.methodType(CallSite.class, Lookup.class, String.class, MethodType.class, String.class),
                "hello");
        indy.invokeExact("indy");
        
        indy = new DynamicIndyGenerator().invokeDynamic("bye",
                MethodType.methodType(void.class, String.class),
                IndyHello.class, "bootstrapMethod",
                MethodType.methodType(CallSite.class, Lookup.class, String.class, MethodType.class, String.class),
                "goodbye");
        indy.invokeExact("indy");
    }
    
    
    public static CallSite bootstrapMethod(Lookup lookup, String name, MethodType type, String text) throws Throwable {
	MethodHandle mh = lookup.findStatic(IndyHello.class, "say",
		MethodType.methodType(void.class, String.class, String.class));
	
	mh = MethodHandles.insertArguments(mh, 0, text);
	
	return new ConstantCallSite(mh);
    }
}
